<?php
// +----------------------------------------------------------------------
// | 奇乐中介担保交易系统 免费版 2019
// +----------------------------------------------------------------------
// | 官方网址：http://www.qilecms.com   
// +----------------------------------------------------------------------
// | 产品文档：http://www.qilecms.com/doc
// +----------------------------------------------------------------------
// | 开发作者: 奇乐CMS
// +----------------------------------------------------------------------
// | 版权说明：这不是一个自由软件！本产品仅限个人使用，但请务必保留底部版权，以免产生不必要的纠纷,
// | 您只能在不用于商业目的的前提下对程序代码进行修改和使用，
// | 任何企业和个人不允许对程序代码以任何形式任何目的再发布。
// +----------------------------------------------------------------------
namespace app\admin\controller;
use think\controller;
class Addons extends Base
{
    // public function initialize()
    // {
    //      partent::initialize();

    
    //     foreach ($adminNav as $key=>$group){
    //         if( isset($base_menu['child'][$key]) ){
    //             $base_menu['children'][$key] = array_merge($base_menu['children'][$key], $group);
    //         }else{
    //             $base_menu['children'][$key] = $group;
    //         }
    //     }
    //      print_r($base_menu);
    //     $this->assign('adminNav',$adminNav); //授权列表
    // }

	public function index()
	{
//获得未安装的插件
       $list= [];

     
        $addons_dir = QL_ROOT.config('addons.addons_dir'); //插件路径
        $dirs = array_map('basename',glob($addons_dir.'/*', GLOB_ONLYDIR)); 

		$addons			=	[];
		$where['name']	=	$dirs;
		$list			=	model('addons')->where($where)->select()->toArray();

		foreach($list as $addon){
			$addon['uninstall']		=	0;
			$addons[$addon['name']]	=	$addon;
		}
		
        foreach ($dirs as $value) {

            if(!isset($addons[$value])){
				$class = get_addon_class($value);
				if(!class_exists($class)){ // 实例化插件失败忽略执行

					continue;
				}

                $obj    =   new $class;
				$addons[$value]	= $obj->info;
				if($addons[$value]){
					$addons[$value]['uninstall'] = 1;
                    $addons[$value]['status'] = -1;
				}
			}
        }  

             $class	= get_addon_class($vo['name']);
                            if(!class_exists($class)){
                                $has_config = 0;
                            }else{
                                $addon = new $class();
                                $has_config = count($addon->getConfig());
             }
      
        $this->assign('list',$addons);

		return $this->fetch();
	}
//安装插件
	public function install()
	{
        $param= $this->request->param();

        $addon_name     =   trim($param['name']);

//判断插件是否存在  
        $where['name']  = $addon_name;
        if (model('addons')->getAddonsCount($where)) {
           return error_json('当前插件已存在');
        }
        $class          =   get_addon_class($addon_name);
        if(!class_exists($class))
        	return error_json('插件不存在');
        $addons  =   new $class;
        $info = $addons->info;

        if(!$info || !$addons->checkInfo())//检测信息的正确性
           return error_json('插件信息缺失');
        session('addons_install_error',null);
        $install_flag   =   $addons->install();
      
        if(!$install_flag){
           $this->error('执行插件预安装操作失败'.session('addons_install_error'));
        }         
	    $res = model('addons')->addData($info);
	    if($res){
           $config['config']         =   str_replace('\\\r\\\n','\r\n',json_encode($addons->getConfig()));
           model('addons')->editData($config,$where);            
	       return success_json('安装成功'); 
	    }else{
	       return error_json('安装失败');
	    }


	}

// 卸载插件
    public function uninstall()
    {
    	$param = $this->request->param();
    	if(!$param['id']){
          return error_json('插件参数错误');
    	}
    	$id = intval($param['id']);
        $where['id'] = $id;
        $res=  model('addons')->delData($where);
        if($res){
          return success_json('卸载成功');  
        }
   
    	
    }

    public function add()
    {
      
        if($this->request->isAjax())
        {
       
                $data                   =   $this->request->param();
                $data['info']['name']   =   trim($data['info']['name']);
                $data['info']['status']   =   !empty($data['info']['status'])?1:0;
                $addonFile              =   $this->preview(false);
                $addons_dir             =   QL_ROOT.config('addons.addons_dir').'/'; //插件路径
                //创建目录结构
                $files          =   [];
                $addon_dir      =   "$addons_dir{$data['info']['name']}/"; //插件目录
                $files[]        =   $addon_dir;
                $addon_name     =   "{$data['info']['name']}.php"; //插件信息类
                $files[]        =   "{$addon_dir}{$addon_name}";
                if($data['has_config'] == 'on')
                {
                    $files[]    =   $addon_dir.'config.php';  //如果有配置文件
                }

                if($data['has_outurl'] =='on')
                {
                    $files[]    =   "{$addon_dir}controller/";
                    $files[]    =   "{$addon_dir}controller/{$data['info']['name']}.php";
                    $files[]    =   "{$addon_dir}model/";
                    $files[]    =   "{$addon_dir}model/{$data['info']['name']}.php";
                }
                //自定义模板
                $custom_config  =   trim($data['custom_config']);
                if($custom_config)
                {
                    $data[]     =   "{$addon_dir}{$custom_config}";
                }

                $custom_adminlist = trim($data['custom_adminlist']);
                if($custom_adminlist)
                {
                    $data[]     =   "{$addon_dir}{$custom_adminlist}";
                }

                create_dir_or_files($files);

// 生成插件扩展控制器  
                //写文件
                file_put_contents("{$addon_dir}{$addon_name}", $addonFile);
                if($data['has_outurl']== 'on')
                {
           
            $addonController = <<<str
<?php
namespace Addons\\{$data['info']['name']}\Controller;
use think\Addons;
/**
 * {$data['info']['name']} 插件信息类
 */
class {$data['info']['name']} extends Addons
{

}

str;

//生成扩展模型类
            file_put_contents("{$addon_dir}/controller/{$data['info']['name']}.php", $addonController);
            $addonModel = <<<str
<?php
namespace Addons\\{$data['info']['name']}\Model;
use think\Model;
/**
 * {$data['info']['name']}模型
 */
class {$data['info']['name']} extends Model
{
    public \$model = [
        'title'         => '',   //新增[title]、编辑[title]、删除[title]的提示
        'template_add'  => '',   //自定义新增模板自定义html edit.html 会读取插件根目录的模板
        'template_edit' => '',   //自定义编辑模板html
        'search_key'    => '',   // 搜索的字段名，默认是title
        'extend'        => 1,
    ];

    public \$_fields = [
        'id'=>[
            'name'    => 'id',  //字段名
            'title'   => 'ID',  //显示标题
            'type'    => 'num', //字段类型
            'remark'  => '',    // 备注，相当于配置里的tip
            'is_show' => 3,     // 1-始终显示 2-新增显示 3-编辑显示 0-不显示
            'value'   => 0,    //默认值
        ],
        'title'=> [
            'name'    => 'title',
            'title'   => '书名',
            'type'    => 'string',
            'remark'  => '',
            'is_show' => 1,
            'value'   => 0,
            'is_must' => 1,
        ],
    ];
}

str;
            file_put_contents("{$addon_dir}/model/{$data['info']['name']}.php", $addonModel);
        }

        //是否需要插件配置
                 if($data['has_config'] == 'on')
                 {  
                    file_put_contents("{$addon_dir}config.php",htmlspecialchars_decode($data['config']));
                    return success_json('插件创建成功');
                  }

        }else{

        $hooks = model('Hooks')->field('name,description')->select();
        $this->assign('Hooks',$hooks);
        return $this->fetch();

        }

    }

//预览
    public function preview($output = true){
        $data                   =   $this->request->param();
        $data['info']['status']   =   !empty($data['info']['status'])?1:0;
        $extend                 =   [];
        $custom_config          =   trim($data['custom_config']);
        if($data['has_config'] && $custom_config){
            $custom_config = <<<str


        public \$custom_config = '{$custom_config}';
str;
            $extend[] = $custom_config;
        }

        $admin_list = trim($data['admin_list']);
        if($data['has_adminlist'] && $admin_list){
            $admin_list = htmlspecialchars_decode($admin_list);
            $admin_list = <<<str

      
        public \$admin_list = [
              {$admin_list}
        ];
str;
           $extend[] = $admin_list;
        }

        $custom_adminlist = trim($data['custom_adminlist']);
        if($data['has_adminlist'] && $custom_adminlist){
            $custom_adminlist = <<<str


        public \$custom_adminlist = '{$custom_adminlist}';
str;
            $extend[] = $custom_adminlist;
        }

        $extend = implode('', $extend);
        $hook = '';
        foreach ($data['hook'] as $value) {
$hook .= <<<str
        //实现的{$value}钩子方法
        public function {$value}(\$param)
        {

        }

str;
        }

        $tpl = <<<str
<?php
namespace addons\\{$data['info']['name']};
use think\Addons;
/**
 * {$data['info']['title']}插件
 * @author {$data['info']['author']}
 */
class {$data['info']['name']} extends  Addons
{

        public \$info = [
            'name'       => '{$data['info']['name']}',
            'title'      => '{$data['info']['title']}',
            'description'=> '{$data['info']['description']}',
            'status'     =>  {$data['info']['status']},
            'author'     => '{$data['info']['author']}',
            'version'    => '{$data['info']['version']}'
        ];{$extend}

        public function install()
        {
            return true;
        }

        public function uninstall()
        {
            return true;
        }

    {$hook}
}
str;


        if($output)
            exit($tpl);
        else
            return $tpl;
    }
	public function unopened()
	{
		$addons = model('addons');
		$list = $addons->getAddonsList('status=0');
       
        $this->assign('list',$list);
		return $this->fetch();
	}
  //开启模块
   public function open()
   {
     $param  = $this->request->param();
     $id     = $param['id'];
     $status = $param['status']; 
     model('addons')->open($id,$status);
     return success_json('插件开启成功');
   }
   public function close()
   {
     $param  = $this->request->param();
     $id     = $param['id'];
     $status = $param['status']; 
     model('addons')->open($id,$status);
     return success_json('插件关闭成功');
   }
   public function config()
   {
   	    $param = $this->request->param();

        if($this->request->isAjax()){
//数据保存
           if(!$param['id']){  return error_json('请求参数错误');}

           $data['config'] = json_encode($param['config']);
           $where['id'] = $param['id'];
           model('addons')->editData($data,$where);
           return success_json('保存成功');
        }else{
                        $id     =   intval($param['id']);
                        $addon  =   model('addons')->find($id);


                        if(!$addon)
                            $this->error('插件未安装');
                        $addon_class = get_addon_class($addon['name']);
                        if(!class_exists($addon_class))
                            trace("插件{$addon['name']}无法实例化,",'ADDONS','ERR');
                        $data  =   new $addon_class;
                      
                        $addon['addon_path'] = $data->addon_path;
                        $addon['custom_config'] = $data->custom_config;
                        $db_config = $addon['config']; //数据库配置
                        $addon['config'] = include $data->config_file;  //插件配置文件信息
                        
                       
                        //获取已经安装的插件配置
                        if($db_config){
                            $db_config = json_decode($db_config, true);
                            $config = $addon['config'];
                            foreach ($config as $key => $value)
                            {
                                if($value['type'] != 'group')
                                {

                                 $config[$key]['value'] = $db_config[$key];
                                     
                                }else{
                                   
                                    foreach ($value['options'] as $gourp => $options)
                                    {
                                        foreach ($options['options'] as $gkey => $value)
                                        {
                                            $addon['config'][$key]['options'][$gourp]['options'][$gkey]['value'] = $db_config[$gkey];
                                        }
                                    }
                                }
                            }
                        }
                        $addon['config'] = $config;

                        $this->assign('data',$addon);

                        if($addon['custom_config'])
                        $this->assign('custom_config', $this->fetch($addon['addon_path'].$addon['custom_config']));

                        return $this->fetch();

        }
       
   }
     /**
     * 插件后台显示页面
     * @param string $name 插件名
     */
    public function adminList($name){
        // 记录当前列表页的cookie
        // Cookie('__forward__',$_SERVER['REQUEST_URI']);
        $this->assign('name', $name);
        $class = get_addon_class($name);
        if(!class_exists($class))
            $this->error('插件不存在');
        $addon = new $class();
        $this->assign('addon', $addon);
        $param = $addon->admin_list;
        if(!$param)
            $this->error('插件列表信息不正确');
        $this->meta_title = $addon->info['title'];
        extract($param);
        $this->assign('title', $addon->info['title']);
        $this->assign($param);
        if(!isset($fields))
            $fields = '*';
        if(!isset($search_key))
            $key = 'title';
        else
            $key = $search_key;
        if(isset($_REQUEST[$key])){
            $map[$key] = ['like', '%'.$_GET[$key].'%'];
            unset($_REQUEST[$key]);
        }


        if(isset($model)){
            $model  =   model("Addons://{$name}/{$model}");
            // 条件搜索
            $map    =  [];
            foreach($_REQUEST as $name=>$val){
                if($fields == '*'){
                    $fields = $model->getDbFields();
                }
                if(in_array($name, $fields)){
                    $map[$name] = $val;
                }
            }
            if(!isset($order))  $order = '';
            $list = $this->lists($model->field($fields),$map,$order);
            $fields = array();
            foreach ($list_grid as &$value) {
                // 字段:标题:链接
                $val = explode(':', $value);
                // 支持多个字段显示
                $field = explode(',', $val[0]);
                $value = array('field' => $field, 'title' => $val[1]);
                if(isset($val[2])){
                    // 链接信息
                    $value['href'] = $val[2];
                    // 搜索链接信息中的字段信息
                    preg_replace_callback('/\[([a-z_]+)\]/', function($match) use(&$fields){$fields[]=$match[1];}, $value['href']);
                }
                if(strpos($val[1],'|')){
                    // 显示格式定义
                    list($value['title'],$value['format']) = explode('|',$val[1]);
                }
                foreach($field as $val){
                    $array = explode('|',$val);
                    $fields[] = $array[0];
                }
            }
            $this->assign('model', $model->model);
            $this->assign('list_grid', $list_grid);
        }
        $this->assign('_list', $list);
        if($addon->custom_adminlist)
            $this->assign('custom_adminlist', $this->fetch($addon->addon_path.$addon->custom_adminlist));
        $this->fetch();
    }
}